import { BaseService, CoolCommException } from "@cool-midway/core";
import { Inject, Provide } from "@midwayjs/core";
import { InjectEntityModel } from "@midwayjs/typeorm";
import { Equal, Repository } from "typeorm";
import { CommentInviteEntity } from "../entity/invite";
import { Context } from "@midwayjs/koa";
import { Utils } from "../../../comm/utils";
import { CommentInfoEntity, RelatedType } from "../entity/info";
import { CommentInfoService } from "./info";
import { AddInviteCommentDTO, AddCommentDTO } from "../dto/info";
import { ProviderProfileEntity } from "../../provider/entity/profile";
import { UserWxService } from "../../user/service/wx";

@Provide()
export class CommentInviteService extends BaseService {
    @InjectEntityModel(CommentInviteEntity)
    commentInviteModel: Repository<CommentInviteEntity>;

    @InjectEntityModel(CommentInfoEntity)
    commentInfoModel: Repository<CommentInfoEntity>;

    @InjectEntityModel(ProviderProfileEntity)
    providerProfileModel: Repository<ProviderProfileEntity>;

    @Inject()
    ctx: Context;

    @Inject()
    utils: Utils;

    @Inject()
    commentInfoService: CommentInfoService;

    @Inject()
    userWxService: UserWxService;

    async list() {
        const queryBuilder = this.commentInviteModel.createQueryBuilder('commentInvite');
        queryBuilder.orderBy('commentInvite.createTime', 'DESC');
        const list = await queryBuilder.getMany();
        return list;
    }

    /**
     * 生成或刷新我的评论邀请码
     */
    async generateInviteCode() {
        const providerId = this.ctx?.provider?.id;
        if (!providerId) {
            throw new CoolCommException('仅支持服务人员生成邀请码');
        }
        const inviteCode = await this.utils.generateUniqueCode(async (code) => {
            return await this.commentInviteModel.exists({
                where: { inviteCode: Equal(code) },
            });
        });
        let invite = await this.commentInviteModel.findOne({
            where: { providerId: Equal(providerId) },
        });
        const inviteTime = new Date();
        if (invite) {
            invite.inviteCode = inviteCode;
            invite.inviteTime = inviteTime;
        } else {
            invite = this.commentInviteModel.create({
                providerId,
                inviteCode,
                inviteTime,
            });
        }
        return await this.commentInviteModel.save(invite);
    }

    /**
     * 获取我的邀请码
     */
    async getMyInvite() {
        const providerId = this.ctx?.provider?.id;
        if (!providerId) {
            throw new CoolCommException('仅支持服务人员查询邀请码');
        }
        const invite = await this.commentInviteModel.findOne({
            where: { providerId: Equal(providerId) },
        });
        if (!invite) {
            return null;
        }

        // const qr = await this.userWxService.getUnlimitedQRCode({
        //     scene: `code=${invite.inviteCode}`,
        //     page: 'pages/comment/invite',
        //     envVersion: this.getMiniProgramEnvVersion(),
        // });

        return {
            ...invite,
            // miniProgramQRCode: qr.base64,
            // miniProgramQRCodeContentType: qr.contentType,
        };
    }

    

    /**
     * 通过邀请码获取服务人员详情
     * @param inviteCode 
     * @returns 
     */
    async getInviteDetail(inviteCode: string) {
        const invite = await this.findInviteByCode(inviteCode);
        const profile = await this.providerProfileModel.findOne({
            where: { providerId: Equal(invite.providerId) },
        });
        if (!profile) {
            throw new CoolCommException('该服务人员暂未完善资料');
        }
        const stats = await this.commentInfoModel.createQueryBuilder('comment')
            .select('COUNT(comment.id)', 'total')
            .addSelect('COALESCE(AVG(comment.averageScore), 0)', 'avg')
            .where('comment.relatedType = :relatedType', { relatedType: RelatedType.PROVIDER })
            .andWhere('comment.relatedId = :providerId', { providerId: invite.providerId })
            .getRawOne();
        const total = Number(stats?.total || 0);
        const avg = Number(Number(stats?.avg || 0).toFixed(1));
        return {
            inviteCode: invite.inviteCode,
            providerId: invite.providerId,
            providerProfile: profile,
            stats: {
                total,
                averageScore: total ? avg : 0,
            },
        };
    }

    /**
     * 用户通过邀请码提交评论
     * @param dto 
     */
    async submitByInvite(dto: AddInviteCommentDTO) {
        const invite = await this.findInviteByCode(dto.inviteCode);
        await this.commentInfoService.add({
            relatedId: invite.providerId,
            relatedType: RelatedType.PROVIDER,
            content: dto.content,
            images: dto.images,
            scoreList: dto.scoreList,
        } as AddCommentDTO);
        return await this.getInviteDetail(dto.inviteCode);
    }

    private async findInviteByCode(inviteCode: string) {
        if (!inviteCode) {
            throw new CoolCommException('邀请码不能为空');
        }
        const invite = await this.commentInviteModel.findOne({
            where: { inviteCode: Equal(inviteCode) },
        });
        if (!invite) {
            throw new CoolCommException('邀请码不存在或已失效');
        }
        return invite;
    }

    private getMiniProgramEnvVersion(): 'release' | 'develop' {
        return process.env.NODE_ENV === 'production' ? 'release' : 'develop';
    }
}